package com.ecoolex.hotel.saas.platform.graphql;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.CollectorUtil;
import com.ecoolex.framework.modularize.api.auth.annotation.PlatformAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.platform.PlatformMemberAuthority;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.hotel.saas.entity.Department;
import com.ecoolex.hotel.saas.entity.Distribution;
import com.ecoolex.hotel.saas.entity.PresaleCoupon;
import com.ecoolex.hotel.saas.entity.PresaleCouponDistribtion;
import com.ecoolex.hotel.saas.entity.PresaleCouponExpirydate;
import com.ecoolex.hotel.saas.enums.PresaleCouponStatus;
import com.ecoolex.hotel.saas.platform.core.PlatformConstant;
import com.ecoolex.hotel.saas.pojo.EditPresaleCouponOneStepDTO;
import com.ecoolex.hotel.saas.pojo.EditPresaleCouponThreeStepDTO;
import com.ecoolex.hotel.saas.pojo.EditPresaleCouponTwoStepDTO;
import com.ecoolex.hotel.saas.ws.OperationService;
import com.ecoolex.hotel.saas.ws.PresaleCouponService;
import com.ecoolex.hotel.saas.ws.StoreService;
import com.google.common.collect.Lists;

@GraphQL2Module(type = Type.Platform, description = "预售券")
@PlatformAuthoritativeRegister(parentKey = PlatformConstant.AUTH_PROJECT_KEY,
	key = PresaleCouponGraphql.AUTH,
	name = "预售券管理",
	remark = "预售券管理")
public class PresaleCouponGraphql {

	public static final String AUTH = PlatformConstant.AUTH_PROJECT_KEY + "-PRESALE-COUPON";
	
	private static final String AUTH_GET = AUTH + "-GET";
	
	private static final String AUTH_QUERY = AUTH + "-QUERY";
	
	private static final String AUTH_EDIT = AUTH + "-EDIT";
	
	private static final String AUTH_DEL = AUTH + "-DEL";
	
	private static final String AUTH_ONLINE = AUTH + "-ONLINE";
	
	private static final String AUTH_OFFLINE = AUTH + "-OFFLINE";
	
	@Reference
	private PresaleCouponService presaleCouponService;
	
	@Reference
	private OperationService operationService;
	
	@Autowired
	private StoreService storeService;
	
	@Autowired
	private StorageService storageService;
	
	@TypeField(type = PresaleCoupon.class, field = "couponDistributionList", description = { "关联的分销对象" })
	public List<PresaleCouponDistribtion> couponDistributionList(@Source PresaleCoupon source){
		return presaleCouponService.queryByPreCouponId(source.getPreCouponId());
	}
	
	@TypeField(type = PresaleCouponDistribtion.class, field = "distribtion", description = { "分销对象" })
	public Distribution distribtion(@Source PresaleCouponDistribtion source) {
		return operationService.getDistribution(source.getDistributionId());
	}
	
	@TypeField(type = Distribution.class, field = "department", description = { "部门" })
	public Department department(@Source Distribution source) {
		return storeService.getDepartment(source.getDepartmentId());
	}
	
	@TypeField(type = PresaleCoupon.class, field = "presaleCouponExpirydate", description = { "有效期策略" })
	public PresaleCouponExpirydate presaleCouponExpirydate(@Source PresaleCoupon source) {
		return presaleCouponService.get(source.getPreCouponId());
	}
	
	@TypeField(type = PresaleCoupon.class, field = "canOnline", description = { "能上线" })
	public Boolean canOnline(@Source PresaleCoupon source, PlatformMemberAuthority user) {
		return user.auth(AUTH_ONLINE) && PresaleCouponStatus.canOnline(source.getStatus());
	}
	
	@TypeField(type = PresaleCoupon.class, field = "canOffline", description = { "能下线" })
	public Boolean canOffline(@Source PresaleCoupon source, PlatformMemberAuthority user) {
		return user.auth(AUTH_OFFLINE) && PresaleCouponStatus.canOffline(source.getStatus());
	}
	
	@TypeField(type = PresaleCoupon.class, field = "canEdit", description = { "能编辑" })
	public Boolean canEdit(PlatformMemberAuthority user) {
		return user.auth(AUTH_EDIT);
	}
	
	@TypeField(type = PresaleCoupon.class, field = "canDelete", description = { "能删除" })
	public Boolean canDel(@Source PresaleCoupon source, PlatformMemberAuthority user) {
		return user.auth(AUTH_DEL) && PresaleCouponStatus.canDel(source.getStatus());
	}
	
	@TypeField(type = PresaleCoupon.class, field = "coverImage", description = { "封面图" })
	public StorageInfo coverImage(@Source PresaleCoupon source) {
		return storageService.get(source.getCoverImage());
	}
	
	@TypeField(type = PresaleCoupon.class, field = "headImage", description = { "头图" })
	public List<StorageInfo> headImage(@Source PresaleCoupon source) {
		if(Check.notNullOrEmpty(source.getHeadImage())) {
			return JSON.parseArray(source.getHeadImage(), String.class).stream()
				.map(storageService::get)
				.filter(Check::notNull)
				.collect(Collectors.toList());
		}
		return Lists.newArrayList();
	}
	
	@QueryField(field = "presaleCoupon", description = { "预售券详情" })
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "预售券详情")
	public PresaleCoupon get(@NonNull Integer preCouponId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_GET);
		return presaleCouponService.getPresaleCoupon(preCouponId);
	}
	
	@QueryField(field = "presaleCouponList", description = { "预售券列表" })
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "预售券列表")
	public Pagination<PresaleCoupon> query(String name,@NonNull Integer storeId,@NonNull Page page, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_QUERY);
		return presaleCouponService.queryPresaleCoupon(name,storeId, page);
	}
	
	@MutationField(field = "editPresaleCoupon", description = "编辑预售券，每一步传入相应参数对象，默认传null")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑预售券")
	public PresaleCoupon edit(EditPresaleCouponOneStepDTO one, EditPresaleCouponTwoStepDTO two,
		EditPresaleCouponThreeStepDTO three, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_EDIT);
		if(Check.notNull(one)) {
			return presaleCouponService.editPresaleCoupon(one, user.userName());
		}else if(Check.notNull(two)) {
			return presaleCouponService.editPresaleCoupon(two, user.userName());
		}else if(Check.notNull(three)) {
			return presaleCouponService.editPresaleCoupon(three, user.userName());
		}
		Assert.throwVerifyException("没有步数据");
		return null;
	}
	
	@MutationField(field = "onlinePresaleCoupon", description = "上线预售券")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_ONLINE, name = "上线预售券")
	public PresaleCoupon online(@NonNull Integer preCouponId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_ONLINE);
		PresaleCoupon presaleCoupon = presaleCouponService.getPresaleCoupon(preCouponId);
		Assert.isTrue(Check.notNull(presaleCoupon),ResultCode.VERIFY.build(1), "预售券不存在");
		return presaleCouponService.onlinePresaleCoupon(presaleCoupon, user.userName());
	}
	
	@MutationField(field = "offlinePresaleCoupon", description = "下线预售券")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_OFFLINE, name = "下线预售券")
	public PresaleCoupon offline(@NonNull Integer preCouponId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_OFFLINE);
		PresaleCoupon presaleCoupon = presaleCouponService.getPresaleCoupon(preCouponId);
		Assert.isTrue(Check.notNull(presaleCoupon),ResultCode.VERIFY.build(1), "预售券不存在");
		return presaleCouponService.offlinePresaleCoupon(presaleCoupon, user.userName());
	}
	
	@MutationField(field = "delPresaleCoupon", description = "删除预售券")
	@PlatformAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除预售券")
	public Boolean delete(@NonNull Integer preCouponId, PlatformMemberAuthority user) {
		user.assertAuth(AUTH_DEL);
		PresaleCoupon presaleCoupon = presaleCouponService.getPresaleCoupon(preCouponId);
		Assert.isTrue(Check.notNull(presaleCoupon),ResultCode.VERIFY.build(1), "预售券不存在");
		return presaleCouponService.delPresaleCoupon(presaleCoupon, user.userName());
	}
	
	@MutationField(field = "uploadPresaleCouponCoverImage", description = { "上传预售券封面" })
	public StorageInfo uploadCoverImage(@NonNull Upload request, PlatformMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("PresaleCoupon", "CoverImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadPresaleCouponHeadImage", description = { "上传预售券头图" })
	public StorageInfo uploadHeadImage(@NonNull Upload request, PlatformMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("PresaleCoupon", "HeadImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
	
	@MutationField(field = "uploadPresaleCouponDetail", description = { "上传预售券图文详情图片" })
	public StorageInfo uploadStoreLogo(@NonNull Upload request, PlatformMemberAuthority user) {
		if (!user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("PresaleCoupon", "Detail");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        return storageService.upload(request, uploadSource, uploadLimit);
	}
}
